import { draw, winuser, dwm } from 'easywin'
import { GetWinList, WindowListItem } from '../util'
import path from 'path'

interface RECT {
  left: number
  top: number
  right: number
  bottom: number
}

globalThis.VWL = null
globalThis.VWA = null

//BUG，vscode自动添加引用时,从types里面引用了。
//显示时调用
globalThis.manager.events[0] = {
  show() {
    globalThis.VWL = new View_Winlist()
    globalThis.VWA = new View_WinAttr()
  },
  beforeRemove() {
    globalThis.VWL = null
    globalThis.VWA = null
  }
}
let winManager = new Proxy({
  index: undefined,
}, {
  set(t, p, v, r) {
    if (p == 'index') {
      if (t[p]) {
        (t[p] as HTMLLIElement).classList.remove('win_item_index')
      }
      (v as HTMLLIElement).classList.add('win_item_index')
    }
    return Reflect.set(t, p, v, r)
  }
})
class View_Winlist {
  winlist: { appWins: WindowListItem[], expWins: WindowListItem[] }
  ul: HTMLUListElement
  constructor() {
    this.init()
  }
  private init() {
    this.ul = document.querySelector("#win_list")
    this.ul.textContent = ''
    //ul绑定单击事件
    this.ul.addEventListener('click', (e) => {
      let path = e.path
      for (let index = 0; index < path.length; index++) {
        let element = path[index] as Element;
        if (element.nodeName == 'LI') {
          winManager.index = element
          globalThis.VWA.render({
            hWnd: +element.getAttribute('_hWnd'),
            title: element.getAttribute('_title'),
            processId: +element.getAttribute('_processId'),
            threadId: +element.getAttribute('_threadId'),
            classname: element.getAttribute('_classname'),
            exeFile: element.getAttribute('_exeFile'),
            hIcon: +element.getAttribute('_Hicon')
          })
          break;
        }
      }
    })
    this.winlist = GetWinList()
    this.winlist.appWins.forEach(item => {
      this.addItem(item)
    })
    this.winlist.expWins.forEach(item => {
      this.addItem(item)
    })
  }
  protected addItem(item: WindowListItem) {
    let li = document.createElement("li")
    //保存属性
    li.setAttribute('_exeFile', item.exeFile)
    li.setAttribute('_classname', item.classname)
    li.setAttribute('_Hicon', item.Hicon + "")
    li.setAttribute('_hWnd', item.hWnd + "")
    li.setAttribute('_processId', item.processId + "")
    li.setAttribute('_threadId', item.threadId + "")
    li.setAttribute('_title', item.title)
    //添加应用图标
    let img = document.createElement("img")
    if (item.Hicon !== 0) {
      let iconBuf = draw.hIconToBuffer(item.Hicon)
      let blob = new Blob([iconBuf], { type: "imageType" })
      let imgUrl = window.URL.createObjectURL(blob)
      img.src = imgUrl
    } else {
      img.src = path.join(process.cwd(), 'public/image/quesheng.png')
    }
    //添加应用文本标识
    let p = document.createElement("p")
    p.textContent = `${item.hWnd}|${item.title}`
    li.appendChild(img)
    li.appendChild(p)
    this.ul.appendChild(li)
  }
}

class View_WinAttr {
  manager = new Proxy({
    hWndClass_element: document.querySelector("#base_hwnd > input[type=text]"),
    hWndClass: undefined,
    hWnd: undefined,
    title_element: document.querySelector("#base_title > input[type=text]"),
    title: undefined,
    rect_element: document.querySelector("#base_pos > input[type=text]"),
    rect: undefined
  }, {
    set(t, p, v, r) {
      if (typeof (v) != 'object') {
        //如果属性有绑定的input，对input进行设置
        if (t[`${(p as string)}_element`]) {
          (t[`${(p as string)}_element`] as HTMLInputElement).value = v + ""
        }
      } else {
        (t[`${(p as string)}_element`] as HTMLInputElement).value = `左边:${v.left},顶边:${v.top},右边:${v.right},底边:${v.bottom}`
      }
      return Reflect.set(t, p, v, r)
    }
  })
  vPos_btn0: HTMLButtonElement
  constructor() {
  }
  render(hWnd: number): void;
  render({ hWnd, title, processId, threadId, classname, exeFile, hIcon }): void;
  render(p: any) {
    switch (typeof (p)) {
      case "number":
        this.manager.hWnd = p
        this.manager.hWndClass = `${p}(${winuser.GetClassName(p)})`
        this.manager.title = `${winuser.GetWindowText(p)}`
        break;

      case "object":
        this.manager.hWnd = p.hWnd
        this.manager.hWndClass = `${p.hWnd}(${p.classname})`
        this.manager.title = `${p.title}`
        break;
    }
    let dwmr = dwm.DwmGetWindowAttribute(this.manager.hWnd, dwm.attrGetFlag.DWMWA_EXTENDED_FRAME_BOUNDS)
    let rect: RECT
    if (dwmr.ok) {
      rect = dwmr.data
    } else {
      let _t = winuser.GetWindowRect(this.manager.hWnd)
      rect = _t
    }
    this.manager.rect = rect
  }
}
